// 规定 某一类型的 公共函数超过3个后 单独写一个文件
import { getIntl } from 'umi';
// import { v4 as uuidv4 } from 'uuid';
// import { uuid } from 'uuidv4';
import BigNumber from 'bignumber.js';
import { Guid } from 'guid-factory/lib/Guid';
import md5 from 'md5';
import moment from 'moment';

import { nanoid } from 'nanoid';

export function nanoid10() {
  return nanoid(10);
}
// 约等于4.77乘以10的28次方
export function nanoid16() {
  return nanoid(16);
}

/**
 * 动态路由根据path查找节点信息
 */
export function findDynamicRoutesNote(data: any, path: string) {
  for (const node of data) {
    if (node.path === path) {
      return node;
    }
    if (node.children) {
      const found: any = findDynamicRoutesNote(node.children, path);
      if (found) {
        return found;
      }
    }
  }
  return null;
}

/**
 * 从本地 public/config中获取json文件
 * @param name json文件名
 * @returns 返回json格式数据
 */
export async function getJson(name: string, path: string = '/'): Promise<any> {
  const res = await fetch(`${path}config/${name}.json`);
  const data = await res.json();
  return data;
}

/**
 * 国际化语法糖 简化 intl.formatMessage 的用法
 * @param id
 * @param defaultMessage
 * @param namedParams
 * @returns
 */
export function intl(id: string, defaultMessage: string | undefined, namedParams?: any): string {
  // 使用全局的
  return getIntl().formatMessage({ id, defaultMessage }, namedParams);
}
/**
 * 国际化 列标题，支持所有 带title类型的
 * 最典型的用法，是用在table的columns中
 * @param intlPrefix 前缀
 * @param items 一般为 column 数组
 * @returns any[]
 * 用法：
 * <Table
 *   columns={ intlItems('test', columns)}
 */
export function intlItems(intlPrefix: string, items: any[], key: string = 'dataIndex'): any[] {
  const newCols = items.map((item: any) => {
    return {
      ...item,
      title: item.title ? intl(`${intlPrefix}.${item[key]}`, item.title) : item.title,
    };
  });
  return newCols;
}

/**
 * 列表转树结构
 * 参考：https://www.cnblogs.com/shb190802/p/13647203.html 有4种方法
 * 注意：必须要有 id pid 字段
 * @param list 后台的数据 []
 * @param opt 选项
 * @returns
 */
export async function list2Tree(
  list: any[],
  opt?: {
    id?: string; // id
    pid?: string; // 父级ID
    pValue?: string; // 顶级节点值 默认  ""
    callback?: (item: any) => boolean; // Promise<API.CurrentUser | undefined>
  },
) {
  const itemObj: any = {};
  let id: string = 'id';
  let pid: string = 'pid';
  let pValue: string = '';
  if (opt) {
    id = opt.id || 'id';
    pid = opt.pid || 'pid';
    pValue = opt.pValue || '';
  }
  list.forEach((item: any) => {
    if (opt && opt.callback) {
      if (opt.callback(item)) {
        itemObj[item[id]] = item;
      }
    } else {
      itemObj[item[id]] = item;
    }
  });
  return list.filter((item: any) => {
    if (item[pid] && item[pid] !== pValue) {
      const obj = itemObj[item[pid]];
      if (obj) {
        if (!obj.children) {
          obj.children = [];
        }
        obj.children.push(item);
      }
      return false;
    }
    return true;
  });
}

/**
 * 树型结构 过滤检索
 * @param treeData
 * @param searchText
 * @param opt.cols 搜索的列，不传全部（但效率低），建议传 opt.children 默认 children
 * @returns 返回一个树型结构
 */
export function filterTreeData(
  treeData: any[],
  searchText: any,
  opt?: {
    cols: any[];
    children?: string;
  },
): any[] {
  const getFullText = (item: any, cols: any): string => {
    let keys: any[] = Object.keys(item);
    if (cols && cols.length > 0) {
      keys = cols;
    }
    let str: string = '';
    keys.forEach((key: string) => {
      str += item[key];
    });
    return str;
  };
  if (!treeData || treeData.length === 0) {
    return [];
  }
  let children = 'children';
  if (opt) {
    children = opt.children || 'children';
  }
  const array: any[] = [];
  treeData.forEach((item: any) => {
    let match: boolean = false;
    const fullText = getFullText(item, opt?.cols);
    match = match || fullText.includes(searchText);
    if (filterTreeData(item[children], searchText, opt).length > 0 || match) {
      array.push({
        ...item,
        children: filterTreeData(item[children], searchText, opt),
      });
    }
  });
  return array;
}

/*
对本地数据搜索
treeData 数据源
searchText 搜索的值
opt.cols 根据那些 键名 进行过滤
*/
export function searchFilterData(
  treeData: any[],
  searchText: any,
  opt?: {
    cols: any[];
  },
): any[] {
  const getFullText = (item: any, cols: any): string => {
    let keys: any[] = Object.keys(item);
    if (cols && cols.length > 0) {
      keys = cols;
    }
    let str: string = '';
    keys.forEach((key: string) => {
      str += item[key];
    });
    return str;
  };
  if (!treeData || treeData.length === 0) {
    return [];
  }
  const array: any[] = [];
  treeData.forEach((item: any) => {
    let match: boolean = false;
    const fullText = getFullText(item, opt?.cols);
    match = match || fullText.includes(searchText);
    if (match) {
      array.push({
        ...item,
      });
    }
  });
  return array;
}

export function formatterTime(val: any): string {
  if (!val) return '';
  const m = moment(val);
  console.log(m.isValid(), val);
  return m.isValid() ? m.format('YYYY-MM-DD HH:mm:ss') : '';
}

export function formatterChinaTime(val: any): string {
  if (!val) return '';
  const m = moment(val);
  return m.isValid() ? m.utcOffset(0).format('YYYY-MM-DD HH:mm:ss') : '';
}

// 获取是否是IE内核浏览器
export const isIEBrowser = () => {
  const ua = window.navigator.userAgent;

  // MSIE内核
  const msie = ua.indexOf('MSIE ');
  if (msie > 0) {
    return parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
  }

  // Trident(又称为MSHTML) 代表：Internet Explorer
  const trident = ua.indexOf('Trident/');
  if (trident > 0) {
    const rv = ua.indexOf('rv:');
    return parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
  }

  return false;
};
/**
 * webpack时把双规划线变为一个
 * @param fileName
 * @returns
 */
export function replaceFileName(fileName: string) {
  return fileName.replace('___', '_').replace('__', '_');
}

// 格 式 化 金 额
export function moneyFormat(num: any, decimal = 2, split = ',') {
  if (isFinite(num) && num && num !== 0) {
    // num是数字
    let res = '';
    const dotIndex = String(num).indexOf('.');
    if (dotIndex === -1) {
      // 整数
      res = String(num).replace(/(\d)(?=(?:\d{3})+$)/g, `$1${split}`) + '.' + '0'.repeat(decimal);
    } else {
      // 非整数
      // js四舍五入 Math.round()：正数时4舍5入，负数时5舍6入
      // Math.round(1.5) = 2
      // Math.round(-1.5) = -1
      // Math.round(-1.6) = -2
      // 保留decimals位小数
      const numStr = String(
        (Math.round(num * Math.pow(10, decimal)) / Math.pow(10, decimal)).toFixed(decimal),
      ); // 四舍五入，然后固定保留2位小数
      const decimals = numStr.slice(dotIndex, dotIndex + decimal + 1); // 截取小数位
      res =
        String(numStr.slice(0, dotIndex)).replace(/(\d)(?=(?:\d{3})+$)/g, `$1${split}`) + decimals;
    }
    // let formatter = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'CNY' });
    // let formatter = new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' });
    // res = formatter.format(num);
    return res;
  } else {
    return ' ';
  }
}

// 数字的 四舍五入，然后固定保留2位小数
export function moneyNumBerFormat(num: number, decimal = 2) {
  if (isFinite(num)) {
    return num.toFixed(decimal);
  } else {
    return 0;
  }
}


export function moneyFormats(nums: any) {
  const regex = /^[0-9,\.]+$/;
  if (regex.test(nums)) {
    const numString = nums;
    const num = Number(numString.replace(/[^0-9.-]+/g, ''));
    const formattedNum = num.toLocaleString(undefined, { minimumFractionDigits: 2 });
    return formattedNum;
  } else {
    return '';
  }
}

// 处理原始数据
export function handleStr(str: any) {
  const arr = str.replace(
    /[`:_.~!@#$%^&*() \+ =<>?"{}|, \/ ;' \\ [ \] ·~！@#￥%……&*（）—— \+ ={}|《》？：“”【】、；‘’，。、]/g,
    '',
  );
  return arr;
}

//节流事件
export function throttle(fn, time = 300) {
  let t: any = null;
  return function (...rest) {
    if (t) return;
    t = setTimeout(() => {
      fn.apply(rest);
      t = null;
    }, time);
  };
}

// 转换 年 月 日 时 秒
export function rTime(date: any) {
  const json_date: any = new Date(date).toJSON();
  const Time = `${new Date(json_date)}${8 * 3600 * 1000}`;
  const attachmentTime = new Date(Time)
    .toISOString()
    .replace(/T/g, ' ')
    .replace(/.[d]{3}Z/, '');
  return attachmentTime.split('.')[0];
}

// 转换 年 月 日
export function rTimes(date: any) {
  const json_date: any = new Date(date).toJSON();
  const Time = `${new Date(json_date)}${8 * 3600 * 1000}`;
  const attachmentTime = new Date(Time)
    .toISOString()
    .replace(/T/g, ' ')
    .replace(/.[d]{3}Z/, '');
  return attachmentTime.split(' ')[0];
}

/**
 *  拼接数组 生成字符串的函数  arrayJoinStr
 * @params  arr:数组
 * @returns `[${arrData}]` 返回处理之后的字符串
 *
 */
// 拼接数组 生成字符串的函数  未审财务数据
export function arrayJoinStr(arr: any[]) {
  const arrData = arr.join('],[').trim();
  return `[${arrData}]`;
}

export interface IGridData {
  header: HeadJson[]; //树形复合表头数据结构
  data: any[][]; //二维数组，表格数据
  cellsMeta: any[]; //单元格设置属性
  tableConfig: any; //表格全局属性
}
export interface HeadJson {
  config?: any;
  key: number | string;
  label: string;
  children?: HeadJson[];
}

// 获取文件名不包含后缀
export function getFileName(name: string) {
  return name.substring(0, name.lastIndexOf('.'));
}

// 获取 .后缀名
export function getExtension(name: string) {
  return name.substring(name.lastIndexOf('.'));
}

/**
 * 对Data进行补零的函数 UpdateCpasTableDataZero
 * @params  cpasTable:  CPAS基础数据data, cmapsData:请求后返回的data, arrangeIndex: 从第n+1列开始处理(默认从第n+1列开始处理)。
 * @returns newCpasTableData 返回处理之后的值
 *
 */
export function UpdateCpasTableDataZeroTemp(
  cpasTable: IGridData,
  cmapsData: any[],
  arrangeIndex: number = 2,
) {
  const zeroData = Array.from({ length: cmapsData.length }, () => 0);
  const newCpasTable = cpasTable.data.map((element: any, index: number) => {
    const lastDta = element[element.length - 1];
    if (index !== 0) {
      element.splice(arrangeIndex, element.length, ...zeroData);
    } else {
      element.splice(arrangeIndex, element.length, ...cmapsData);
    }
    element.push(lastDta);
    return element;
  });
  return newCpasTable;
}

/**
 * 插入数据 UpdateCPASTableData
 * @params  resultData:请求后返回的data, cpasTableData:  CPAS基础数据data, arrangeIndex: 从第n+1列开始处理(默认从第n+1列开始处理)。
 * @returns newCpasTableData 返回处理之后的值
 *
 */
export function UpdateCPASTableDataTemp(
  resultData: any[],
  cpasTableData: any[],
  arrangeIndex: number = 2,
) {
  let newCpasTableData = cpasTableData.map((arr) => [...arr]);
  console.log('参数---    数据@@@', resultData, cpasTableData, newCpasTableData);
  // 将 resultData 数组中的值写入 newCpasTableData 数组中
  newCpasTableData = newCpasTableData.map((row, i) => {
    // 第一行 不处理
    const name: any = row[0]?.trim() ?? '';
    if (i !== 0 && name) {
      const rowData: any = resultData.find(
        (data) => data.itemName === name || data.ItemName === name,
      );
      const newRow: any = rowData
        ? Object.values(rowData).slice(1)
        : row.slice(arrangeIndex, row.length - 1).fill(0);
      return [...row.slice(0, arrangeIndex), ...newRow, row[row.length - 1]];
    }
    return row;
  });
  console.log('返回---   数据@@@', newCpasTableData);

  return newCpasTableData;
}

/** UpdateCpasTableHeader  生成新的CpasTableHeader 修改HeaderData的函数
 *  @params cpasTable 当前的cpasTable数据 ,arrangeIndex: 从第几列开始处理(默认从第2列开始处理)。
 *  @params yearData 多年度的数组  [2016,2017,2018],
 *  @returns newHeaderData; 处理好的头部data
 */
export function UpdateCpasTableHeader(
  cpasTableHeader: any[],
  yearDataTitle: any[],
  arrangeIndex: number = 2,
  tableTitleChange: boolean,
) {
  const cpasTableHeaderData = cpasTableHeader;
  // let newHeaderData: any = cpasTableHeaderData.splice(0, arrangeIndex);
  console.log('最初头部的数据@@@', cpasTableHeaderData);

  const last2Config = cpasTableHeaderData[cpasTableHeaderData.length - 2];
  // const newYearStr: any[] = yearDataTitle;
  // const minNum = Math.min(...yearData);
  // const tableTitleQC = tableTitleChange ? '期初余额' : '上期发生额';
  // const tableTitleQM = tableTitleChange ? '期末余额' : '本期发生额';
  // yearData.forEach((YY: any) => {
  //   const beforeYY = yearData.length > 1 ? YY : '';
  //   newYearStr.push(`${beforeYY}${tableTitleQM}`);
  //   if (YY === minNum) {
  //     newYearStr.push(`${beforeYY}${tableTitleQC}`);
  //   }
  // });

  const tableDataLength = cpasTableHeader.length - arrangeIndex - 1;
  const cmapsDataLength = yearDataTitle.length;

  const copyData: any = [];

  console.log('数据@@@', yearDataTitle, cmapsDataLength, tableDataLength);

  for (let i = 0; i < cpasTableHeaderData.length; i++) {
    const item = cpasTableHeaderData[i];
    if (i < arrangeIndex || i === cpasTableHeaderData.length - 1) {
      copyData.push(item);
    } else {
      const label = yearDataTitle[i - arrangeIndex];
      if (label) {
        const config = item.config;
        copyData.push({
          label,
          key: Guid.newGuid(),
          config,
        });
      }
    }
  }
  console.log('当出现 大于tableData头部数据时@@@', cmapsDataLength, tableDataLength);
  if (cmapsDataLength > tableDataLength) {
    yearDataTitle.forEach((item, index) => {
      if (index >= tableDataLength) {
        copyData.splice(copyData.length - 1, 0, {
          label: item,
          key: Guid.newGuid(),
          config: last2Config.config,
        });
      }
    });
  }

  console.log('返回的头部数据@@@', copyData);

  return copyData;
}

/**
 * 对Data进行补零的函数 UpdateCpasTableDataZero
 * @params  cpasTableData:  CPAS基础数据data, cmapsData:请求后返回的data, arrangeIndex: 从第n+1列开始处理(默认从第n+1列开始处理)。
 * @returns newCpasTableData 返回处理之后的值
 *
 */
export function UpdateCpasTableDataZero(
  cpasTableData: any[],
  cmapsData: any[],
  arrangeIndex: number = 2,
) {
  console.log('UpdateCpasTableDataZero--  start    数据@@@', cpasTableData, cmapsData);
  let newCpasTable: any[] = [];
  const tableDataLength = cpasTableData[0].length - arrangeIndex - 1;
  const cmapsDataLength = cmapsData.length;

  if (cmapsDataLength === tableDataLength) {
    newCpasTable = cpasTableData.map((element: any, index: number) => {
      const lastDta = element[element.length - 1];
      if (index === 0) {
        element.splice(arrangeIndex, element.length, ...cmapsData);
        element.push(lastDta);
      }
      return element;
    });
    console.log(' UpdateCpasTableDataZero 返回---end  数据@@@', newCpasTable);
    return newCpasTable;
  } else if (cmapsDataLength > tableDataLength) {
    const differenceLength = cmapsDataLength - tableDataLength;
    const zeroData = Array.from({ length: differenceLength }, () => 0);
    newCpasTable = cpasTableData.map((element: any, index: number) => {
      if (index !== 0) {
        element.splice(element.length - 1, 0, ...zeroData);
      } else {
        const lastDta = element[element.length - 1];
        element.splice(arrangeIndex, element.length, ...cmapsData);
        element.push(lastDta);
      }
      return element;
    });
    console.log(' UpdateCpasTableDataZero 返回---end  数据@@@', newCpasTable);
    return newCpasTable;
  }

  const differenceLength = tableDataLength - cmapsDataLength;
  newCpasTable = cpasTableData.map((element: any, index: number) => {
    if (index !== 0) {
      element.splice(element.length - differenceLength - 1, differenceLength);
    } else {
      const lastDta = element[element.length - 1];
      element.splice(arrangeIndex, element.length, ...cmapsData);
      element.push(lastDta);
    }
    return element;
  });
  console.log(' UpdateCpasTableDataZero 返回---end  数据@@@', newCpasTable);

  return newCpasTable;
}

// 替换公司内的 {year}+1/{year}-1
function replaceDynamicMathInFormula(formula: string, baseYear: number) {
  const replacedFormula = formula.replace(/{year}([\+\-]\d+)?/g, (match: any, p1: any) => {
    // 如果有匹配的数字，则执行相应的加减操作
    if (p1) {
      const offset = parseInt(p1, 10);
      return `${baseYear + offset}`;
    }
    // 没有匹配的数字，直接使用基准年份
    return `${baseYear}`;
  });

  return replacedFormula;
}

export function UpdateCPASTableData(
  resultData: any[],
  cpasTableData: any[],
  arrangeIndex: number = 2,
  negationRow: string[] = [],
  year: string = '',
) {
  // debugger;
  console.time();
  console.log('参数--- start    数据@@@', resultData, cpasTableData, arrangeIndex);
  let tempYear = -1;
  if (year) {
    tempYear = Number(year);
  }
  const dataMap = new Map(resultData.map((item) => [item.itemName || item.ItemName, item]));
  const headers = cpasTableData[0];
  const headersLength = cpasTableData[0].length - 1; // 最后一位的索引号;
  const headerLookup = headers.reduce((lookup: any, header: any, index: number) => {
    lookup[index] = header;
    return lookup;
  }, {});
  console.log('map   数据@@@', dataMap);
  const newCpasTableData = cpasTableData.map((row, rowIndex) => {
    if (rowIndex === 0 || !row[0]) return row;
    // 判断行聚合 列聚合
    const rowIndexOf = row[0].indexOf('|');
    if (rowIndexOf !== -1) return row;
    const itemNames = row[0].trim();
    const dataMapRow = dataMap.get(itemNames);
    console.log('@@@ 取回的数据', dataMapRow);
    // if (!dataMapRow) return row;
    const newRow = row.map((col: any, colIndex: number) => {
      // 判断有公式直接返回，公式优先=FS_CELL("base.reportItems","货币资金-库存现金","审定数","{year}+1")  2018+1=2019
      if (col && col.startsWith('=')) {
        if (tempYear < 0) return col;
        const replacedFormula = replaceDynamicMathInFormula(col, tempYear);
        return replacedFormula;
      }
      if (!dataMapRow || colIndex < arrangeIndex || colIndex === headersLength) return col;
      const headerName = headerLookup[colIndex];
      let findIndex = -2;
      let bbbColValue = 0;
      if (negationRow.length > 0) {
        const rowName = dataMapRow.itemName || dataMapRow.ItemName;
        findIndex = negationRow.indexOf(rowName);
      }
      if (findIndex >= 0) {
        bbbColValue = dataMapRow ? dataMapRow[headerName] * -1 : col;
      } else {
        bbbColValue = dataMapRow ? dataMapRow[headerName] : col;
      }
      return bbbColValue;
    });
    return newRow;
  });
  console.timeEnd();
  console.log('返回---end    数据@@@', newCpasTableData);

  return newCpasTableData;
}

export function CellsMetaUpdateCPASTableData(
  cellsMetaData: any[],
  allRowsMaps: any[],
  verifyByRMapObj: any,
) {
  for (const key in verifyByRMapObj) {
    const rowIndex = allRowsMaps.indexOf(key) + 1;
    // console.log(key, rowIndex, '!!!@@@');

    // 如果找到了 key 在 aaa 中的索引
    if (rowIndex !== -1) {
      // console.log(key, verifyByRMapObj[key], '!!!@@@');
      for (let index = 0; index < cellsMetaData.length; index++) {
        const item = cellsMetaData[index];
        if (item.row === rowIndex && item.col === 1) {
          // 根据 verifyByRMapObj[key].verify 的值，填充到 cellsMetaData 项的 custom 对象中
          if (item?.custom) {
            let verifyObj: any = {};
            delete item.custom["successMark"]
            delete item.custom["errorMark"]
            if (verifyByRMapObj[key].verify) {
              verifyObj = { successMark: true };
            } else {
              verifyObj = { errorMark: true };
            }
            item.custom = {
              ...item.custom,
              ...verifyObj,
            };
          }
        }
      }
    }
  }

  return cellsMetaData;
}

export function sizeToReadable(size: number) {
  let data = '';
  if (size < 0.1 * 1024) {
    //如果小于0.1KB转化成B
    data = size.toFixed(2) + `<span style='font-size:15px;font-weight: 500;'>B</span>`;
  } else if (size < 0.1 * 1024 * 1024) {
    //如果小于0.1MB转化成KB
    data = (size / 1024).toFixed(2) + `<span style='font-size:15px;font-weight: 500;'>KB</span>`;
  } else if (size < 0.1 * 1024 * 1024 * 1024) {
    //如果小于0.1GB转化成MB
    data =
      (size / (1024 * 1024)).toFixed(2) +
      `<span style='font-size:15px;font-weight: 500;'>MB</span>`;
  } else {
    //其他转化成GB
    data =
      (size / (1024 * 1024 * 1024)).toFixed(2) +
      `<span style='font-size:15px;font-weight: 500;'>GB</span>`;
  }
  return data;
}

/**
 * 删除满足条件的数组
 * @params  oldData:  需要删除数据的原数组, fieldStr:键值名, conditionStr: 条件。
 * @returns newDelData 返回处理之后的值
 *
 */
// 删除满足条件的
export function delArray(oldData: any[], fieldStr: string, conditionStr: string) {
  const newDelData = oldData.filter((item) => {
    return !conditionStr.includes(item[fieldStr]);
  });
  return newDelData;
}

/**
 * changeShowTitleTime函数 更改
 * @params params参数  isAllTime是否显示完整的年月日 , ADateS 开始时间, ADateE 结束时间
 * @returns showTitleTime 返回需要展示的时间格式
 *
 */
export const changeShowTitleTime = (params: {
  isAllTime: boolean;
  ADateS?: string;
  ADateE?: string;
  byMonthData?: any;
}) => {
  let showTitleTime = '';
  const { isAllTime, ADateS, ADateE, byMonthData } = params;
  if (byMonthData) {
    const byYear = `${byMonthData}`.slice(0, 4);
    const byMonth = `${byMonthData}`.slice(4);
    const byDays = moment(`${byYear}-${byMonth}-01`).daysInMonth();
    showTitleTime = `${byYear}年${byMonth}月${byDays}日`;
  } else {
    const ndYear = `${moment(ADateS).year()}`;
    const moothStart = moment(ADateS).month() + 1;
    const moothEND = moment(ADateE).month() + 1;
    const dayEND = moment(ADateE).date();

    if (isAllTime) {
      showTitleTime = `${ndYear}年${moothEND}月${dayEND}日`;
    } else {
      if (moothStart === 1 && moothEND === 12) {
        showTitleTime = `${ndYear}年度`;
      } else {
        showTitleTime = `${ndYear}年${moothStart}-${moothEND}月`;
      }
    }
  }
  return showTitleTime;
};

/**
 * 调用 CPAS的exe函数 附件平台导入之后
 * @params params参数  usercode: string;password: string;zcbfid: string;
 *
 *
 */
export function syncCpasexeFJ(params: {
  usercode: string;
  password: string;
  zcbfid: string;
  BusType: number;
  BusID?: string;
}) {
  const paramsObj = {
    argType: 'c',
    u: params.usercode,
    p: params.password,
    zcbfid: params.zcbfid,
    BusAction: 'u',
    BusType: params.BusType,
    BusID: params.BusID,
    callback: {},
  };
  const Parameter = JSON.stringify(paramsObj);

  console.log(
    `cpas://OpenLocalFile/?fileName=./CpasCloudSvr/CpasCloudSvr.exe&params=${Parameter}`,
    '@@@ syncCpasexeFJ',
  );

  window.location.href = `cpas://OpenLocalFile/?fileName=./CpasCloudSvr/CpasCloudSvr.exe&params=${Parameter}`;
}

/**
 * 调用 CPAS的exe函数 值提供 底稿平台和附件平台进行同步
 * @params params参数  usercode: string;password: string;zcbfid: string;
 *
 *
 */
export function CallingCpasexe(params: {
  usercode: string;
  password: string;
  zcbfid: string;
  BusType: number;
}) {
  const paramsObj = {
    argType: 'c',
    u: params.usercode,
    p: params.password,
    zcbfid: params.zcbfid,
    BusType: params.BusType,
    BusAction: 's',
    ShowBusFrm: true,
  };
  const Parameter = JSON.stringify(paramsObj);
  window.location.href = `cpas://OpenLocalFile/?fileName=./CpasCloudSvr/CpasCloudSvr.exe&params=${Parameter}`;
}

export function EntrySynchronizationMethod(params: {
  usercode: string;
  password: string;
  zcbfid: string;
  BusID: string;
  tag?: string;
  BusType?: number;
}) {
  const paramsObj = {
    argType: 'c',
    u: params.usercode,
    p: params.password,
    zcbfid: params.zcbfid,
    BusType: params.BusType ? params.BusType : 2,
    BusID: params.BusID,
    BusAction: 's',
    ShowBusFrm: false,
    callback: {
      type: 'http',
      address: `${localStorage.getItem('cpasApiUrl')}/office/syncState`,
      token: localStorage.getItem('cpasToken'),
      tag: params.tag,
    },
  };

  const Parameter = JSON.stringify(paramsObj);
  console.log(`cpas://OpenLocalFile/?fileName=./CpasCloudSvr/CpasCloudSvr.exe&params=${Parameter}`);

  window.location.href = `cpas://OpenLocalFile/?fileName=./CpasCloudSvr/CpasCloudSvr.exe&params=${Parameter}`;
}

// // 判断是否为原始数据
// export function IsPrimitive(isNewAdd,KMMC) {
//   const newDelData = oldData.filter(item => {
//     return !conditionStr.includes(item[fieldStr]);
//   });
//   return newDelData;
// }
export const changeTitleTime = (ADateS: string, ADateE: string) => {
  let showTimeA = '';
  let showTimeB = '';
  let ndYear = '';
  const momentType = 'YYYY年MM月DD日';
  const moothStart = moment(ADateS, momentType).month() + 1;
  const moothEND = moment(ADateE, momentType).month() + 1;
  const sYear = moment(ADateS, momentType).year();
  const eYear = moment(ADateE, momentType).year();

  if (sYear > eYear) {
    ndYear = `${sYear}`;
  } else if (sYear < eYear) {
    ndYear = `${eYear}`;
  } else {
    ndYear = `${sYear}`;
  }

  if (sYear === eYear) {
    if (moothStart > moothEND) {
      showTimeA = moment(ADateS, momentType).format(momentType);
    } else {
      showTimeA = moment(ADateE, momentType).format(momentType);
    }
  } else {
    if (sYear > eYear) {
      showTimeA = moment(ADateS, momentType).format(momentType);
    } else {
      showTimeA = moment(ADateE, momentType).format(momentType);
    }
  }
  if (sYear === eYear) {
    if ((moothEND === 1 && moothStart == 12) || (moothStart === 1 && moothEND == 12)) {
      showTimeB = `${ndYear}年度`;
    } else {
      if (moothStart > moothEND) {
        showTimeB = `${ndYear}年${moothEND}-${moothStart}月`;
      } else {
        showTimeB = `${ndYear}年${moothStart}-${moothEND}月`;
      }
    }
  } else {
    if (moothStart === 12 && moothEND === 12) {
      showTimeB = `${ndYear}年度`;
    } else if (moothEND === 12) {
      showTimeB = `${ndYear}年1-${moothStart}月`;
    } else if (moothStart === 12) {
      showTimeB = `${ndYear}年1-${moothEND}月`;
    }
  }

  return { titleTimeA: showTimeA, titleTimeB: showTimeB };
};

/**
 * 重置节点pid
 * @param data
 * @returns
 */
export function resetPidIfNotFound(data: any) {
  const map = new Map(data.map((item: any) => [item.id, item]));
  for (const item of data) {
    if (item.pid && !map.has(item.pid)) {
      item.pid = null;
      if (item.parentId) {
        item.parentId = null;
      }
    }
  }
  return data;
}

/**
 * DataId_Name 联合主键生成方式
 */
export function keyByMd5(dataId: string, name: string) {
  return Md5_16(dataId + name);
}

/**
 * 16位 md5算法
 * @param str
 * @constructor
 */
export function Md5_16(str: string) {
  return md5(str).substring(8, 24);
}

//列格式化金额
export function moneyFormatCol(value: any, isShow0: boolean = true, d: number = 2) {
  // if (typeof value === 'string') {
  //   value = value.replace(/,/g, '');
  // }
  if (!value && isShow0) return '0.00';
  if (!value && !isShow0) return '';

  // if (isEditing || typeof value === 'string') {
  //   // Return the original numeric value when editing
  //   return parseFloat(value.replace(/[^\d.]/g, ''));
  // }
  const formattedNumber = new Intl.NumberFormat('zh-CN', {
    style: 'currency',
    currency: 'CNY',
    maximumFractionDigits: d,
  }).format(value);
  const withoutCurrencySymbol = formattedNumber.replace(/[^\d,-.]+/g, '');
  return withoutCurrencySymbol;
}

export function pushNumberData(numStr: any, d: number = 2) {
  let truncatedNumber = '0.00';
  let formattedPrice = '0.00';
  if (!numStr || numStr === 'null' || numStr === 'NAN' || numStr === '0') {
    return {
      success: false,
      truncatedNumber,
      formattedPrice,
    };
  }
  const toStr = numStr.toString();
  const cleanedValue = toStr?.replace(/[^0-9,-.]/g, '');
  const numericValue = cleanedValue?.replace(/,/g, '')?.replace(/(\..*)\./g, '$1');
  if (!isNaN(numericValue)) {
    const num = new BigNumber(numericValue);
    truncatedNumber = num.toFixed(d);
    // truncatedNumber = num.dp(d, BigNumber.ROUND_HALF_UP).toString();
    // truncatedNumber = num.round(0, BigNumber.ROUND_HALF_UP).toString();
    formattedPrice = moneyFormatCol(truncatedNumber, d);
    return {
      success: true,
      truncatedNumber,
      formattedPrice,
    };
  }
  return {
    success: false,
    truncatedNumber,
    formattedPrice,
  };
}

// 提取文件地址和文件名
export const extractFileInfo = (path: any) => {
  const parts = path.split(/[\\/]/); // 使用正则表达式分隔路径
  const fileName = parts.pop().split('.')[0]; // 弹出最后一个部分作为文件名
  const dirName = parts.join('/'); // 剩余部分拼接为文件地址
  return { dirName, fileName };
};

export const getAllParentData = (node: any) => {
  const parentArr: any = [];
  let current = node;
  while (current && current.level >= 0) {
    parentArr.push(current.key);
    current = current.parent;
  }
  return parentArr;
};

export const getChild = (node: any) => {
  const arr: any = [];
  // 定义一个函数
  function findFunc(node: any) {
    if (node.children && node.children.length) {
      for (let i = 0, len = node.children.length; i < len; i++) {
        findFunc(node.children[i]);
      }
    } else {
      arr.push(node);
    }
    return arr;
  }
  findFunc(node);
  return arr;
};

/**
 * 按照深度递归的顺序，平铺节点
 */
const deepTree = (data: any, arr: any[] = []) => {
  for (let i = 0; i < data.length; i++) {
    const item: any = data[i];
    const clone_item = _.cloneDeep(item);
    delete clone_item.children;
    arr.push(clone_item);
    if (item.children && item.children.length) {
      deepTree(item.children, arr);
    }
  }
  return arr;
};

/**
 * 平级结构转数树结构
 * @param score
 * @param pid
 */
function convertLevelToTree(score: any, pid = null) {
  const tree: any = [];
  score.map((item: any) => {
    if (item.pid === pid) {
      // 递归寻找
      item.children = convertLevelToTree(score, item.id);
      tree.push(item);
    }
  });
  return tree;
}
/**
 * 重新排序一下树节点,按照深度递归的顺序，平铺节点
 */
export function sortTreeByChildren(data: any, sourceTreeData: any) {
  // 从库里查出来的数据会保证同级下的顺序数组，order by pid,orderNumber.
  // 所以直接转成树形结构会保证同级下的顺序
  // 由于数据库里没有存储level层级，所以需要先转成树形结构，再按照深度递归的方式转成平铺的数组
  //const dataId = await getDataId()
  // 获取原树
  //const resData = await getLeftTreeList(dbname, dataId);
  const sourceTreeArr: any = [];
  // 按照深度递归平铺原树
  deepTree(convertLevelToTree(sourceTreeData), sourceTreeArr);
  // 检测无父ID的提升 , 勾稽汇总的树
  const resetTargetData = resetPidIfNotFound(data);
  // 按照原树进行填充位置
  let sort_arr = new Array(sourceTreeArr.length).fill(null);
  // 进行位置对比，将勾稽汇总的树。按照源树进行排序
  for (let i = 0; i < resetTargetData.length; i++) {
    for (let j = 0; j < sourceTreeArr.length; j++) {
      if (resetTargetData[i].id === sourceTreeArr[j].id) {
        sort_arr[j] = resetTargetData[i];
      }
    }
  }
  //过滤掉无用Null占位
  sort_arr = sort_arr.filter((item) => item !== null);
  return sort_arr;
}

//循环查找父节点
export function loopParentTreeList(data: any, allData: any) {
  if (!data || !data.length) {
    return;
  }
  let result: any = data.slice();
  const parentIds: any = [];
  for (let i = 0; i < data.length; i++) {
    const current = data[i];
    // const res = result.filter((item: any) => item.fid === current.fid);
    if (current.parentId && !parentIds.includes(current.parentId)) {
      parentIds.push(current.parentId);
    }
  }
  if (parentIds && parentIds.length) {
    for (let i = 0; i < parentIds.length; i++) {
      const parentId = parentIds[i];
      const parentData = allData.filter((item: any) => item.fid === parentId);
      if (parentData && parentData.length) {
        const res = loopParentTreeList(parentData, allData);
        if (res && res.length) {
          result = result.concat(res);
        }
      }
    }
  }
  result.map((item: any) => {
    item.expanded = true;
  });
  return unique(result);
}

//数组去重
function unique(arr: any) {
  const resIds: any = [];
  const res = [];
  for (let i = 0; i < arr.length; i++) {
    if (!resIds.includes(arr[i].fid)) {
      resIds.push(arr[i].fid);
      res.push({
        ...arr[i],
      });
    }
  }
  return res;
}

export function fjAndDgDataCode(dataCode: any) {
  let reText = '';
  if (dataCode === '009') {
    reText = '名称重复';
  } else if (dataCode === '010') {
    reText = '索引号重复';
  } else if (dataCode === 'ENOENT') {
    reText = '未找到文件';
  } else if (dataCode === 'EBUSY') {
    reText = '文件被打开';
  } else if (dataCode === '404') {
    reText = '库里未找到该数据';
  } else if (dataCode === 'IO_UN_KNOW') {
    reText = '本地I0未知错误';
  } else if (dataCode === 'EPERM') {
    reText = '没有操作交件权限';
  } else if (dataCode === '011') {
    reText = 'sql入库失败';
  } else {
    reText = dataCode;
  }
  return reText;
}

export function resDataFilter(nrwData: any[] | string) {
  let tempSucc: any = [];
  let tempError: any = [];
  if (Array.isArray(nrwData)) {
    tempSucc = nrwData?.filter((item: any) => item.code === '200') ?? [];
    tempError = nrwData?.filter((item: any) => item.code !== '200') ?? [];
    tempError.forEach((item: any) => {
      item.itemKey = nanoid10()
    })
    return {
      reDataArr: {
        tempSucc,
        tempError,
      },
      success: true,
    };
  }
  return {
    reDataArr: {
      tempSucc: [],
      tempError: [],
    },
    success: false,
  };
}

export async function waitTime(time: number = 100) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(true);
    }, time);
  });
}

export const numberTotalMethod = (
  arrayData: any,
  isHCFSETotal: boolean = false,
  fixedNumber: number = 2,
) => {
  if (arrayData.length === 0)
    return {
      totaldF_res: '0.00',
      totaldF_resNumber: 0.0,
      totaljF_res: '0.00',
      totaljF_resNumber: 0.0,
    };

  let totaldF_result = new BigNumber(0.0);
  let totaljF_result = new BigNumber(0.0);
  if (isHCFSETotal) {
    for (let i = 0; i < arrayData.length; i++) {
      if (arrayData[i]?.isHCFSE) {
        const dF = arrayData[i]?.DF || 0.0;
        const jF = arrayData[i]?.JF || 0.0;
        totaldF_result = totaldF_result.plus(dF);
        totaljF_result = totaljF_result.plus(jF);
      }
    }
  } else {
    for (let i = 0; i < arrayData.length; i++) {
      const dF = arrayData[i]?.DF || 0.0;
      const jF = arrayData[i]?.JF || 0.0;
      totaldF_result = totaldF_result.plus(dF);
      totaljF_result = totaljF_result.plus(jF);
    }
  }

  const aaaJF = pushNumberData(`${totaljF_result.toFixed(fixedNumber)}`);
  const bbbDF = pushNumberData(`${totaldF_result.toFixed(fixedNumber)}`);
  return {
    totaldF_res: bbbDF.formattedPrice,
    totaldF_resNumber: Number(bbbDF.truncatedNumber),
    totaljF_res: aaaJF.formattedPrice,
    totaljF_resNumber: Number(aaaJF.truncatedNumber),
  };
};

export const isValidExpression = (expression: string) => {
  const operators = /[+\-*/]/;
  const validChars = /[0-9a-zA-Z()]+/;
  let balance = 0;
  let prevChar = '';

  for (let i = 0; i < expression.length; i++) {
    const char = expression[i];

    // 检查字符是否合法
    //   if ( !operators.test(char) && char !== ' ') {
    //     return false;
    //   }

    // 检查括号匹配
    if (char === '(') {
      balance++;
    } else if (char === ')') {
      if (balance === 0) {
        return '括号不匹配'; // 括号过多
      }
      balance--;
    }

    // 检查运算符的合法性
    if (operators.test(char)) {
      // 不允许以运算符开始或结束，也不允许两个运算符相邻
      if (prevChar === '' || prevChar === '(' || operators.test(prevChar)) {
        return '运算符不对';
      }
    }

    prevChar = char;
  }

  // 检查括号是否匹配
  if (balance !== 0) {
    return '括号不匹配';
  }

  // 表达式不能以运算符结束
  if (operators.test(prevChar)) {
    return '运算符不对';
  }

  return '合法';
};
